package com.mattgarner.jaddas.node.command;

import java.util.Formatter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.mattgarner.jaddas.common.ResultSet;
import com.mattgarner.jaddas.node.CurrentStateManager;
import com.mattgarner.jaddas.node.ErrorLogManager;
import com.mattgarner.jaddas.node.RemoteClient;
import com.mattgarner.jaddas.node.net.Message;
import com.mattgarner.jaddas.node.net.Protocol;
import com.mattgarner.jaddas.node.net.Worker;

public class CommandParser {
	private Worker worker;
	private RemoteClient clientConfig;
	protected ErrorLogManager logManager;
	protected CurrentStateManager stateManager;
	protected long commandExecutionStartTime;
	
	public CommandParser(Worker serverWorker, RemoteClient client) {
		commandExecutionStartTime = System.nanoTime();
		worker = serverWorker;
		clientConfig = client;
		logManager = ErrorLogManager.getInstance();
		stateManager = CurrentStateManager.getInstance();
	}
	
	public  boolean processCommand(Message message) {
		return false;
	}
	
	
	// utilities
	public String preprocessCommandString(String command) {
		command = command.replaceFirst("^\\s*", ""); // heading white space 
		command = command.replaceFirst("\\s*$", ""); // trailing white space
		command = command.replaceFirst(";$", ""); // trailing semicolon
		return command;
	}
	
	public String[] extractRegexGroups(String regex, String inputString) {
		Pattern p;
		Matcher m;
		try { 
			p = Pattern.compile(regex);
			m = p.matcher(inputString);
			m.find();
			String[] output = new String[m.groupCount()];
			for(int a = 0; a<m.groupCount(); a++) {
				output[a] = m.group(a+1);
			}
			return output;
		} catch(IllegalStateException e) {
			String[] output = new String[16];
			for(int b=0; b<output.length; b++) { 
				output[b] = "";
			}
			return output;
		}
	}
	
	// 
	protected final RemoteClient getRemoteClient() {
		return clientConfig;
	}
	
	protected final Worker getServerWorker() {
		return worker;
	}
	
	protected final void sendResultSet(ResultSet resultSet) {
		worker.sendMessage(new Message(Protocol.MSG_RESULTSET_HEADER, resultSet.getHeader().getHeaderDataStream()));
		worker.sendMessage(new Message(Protocol.MSG_RESULTSET_ROW, resultSet.getFullResultSetData()));
		worker.sendMessage(Protocol.MSG_OK, "Server sent "+resultSet.getRowCount()+" rows. (executed in "+calculateExecuteTime()+" sec.)");
	}
	
	protected final double calculateExecuteTime() {
		Float executeTime = new Float(System.nanoTime() - commandExecutionStartTime) / 1000000000;
		Formatter formatter = new Formatter();
		return new Double(formatter.format("%.4f", executeTime).toString());
	}
}
